home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Fchart -- fgraf.c
- *
- * Copyright (C) 1990 Piotr Filip Sawicki
- *
- * WARNING:
- * Included "fstyles.i" is an older version of already rewritten graphics
- * module. Please, don't change anything, rather mail me suggestions.
- * It emerged like a ball of mud -- don't be shocked with this code.
- * Writing program I jjust have been adding here new styles, parameters,
- * bells and whistles -- so it looks like it looks.
- *
- * Rest of the code can be freely modified and used, as long as this message
- * is retained and modified code is not redistributed.
- *
- * Please e-mail any useful additions to fs@uwasa.fi so they may be
- * included in later releases.
- *
- * This file should be edited with 4-column tabs! (:set ts=4 sw=4 in vi)
- */
-
- #include <stdio.h>
- #include <math.h>
- #include "plot.h"
- #include "fchart.h"
-
- /***********************************************************************/
-
- #define MARGIN 0.95 /* margin within frame */
-
- /***********************************************************************/
-
-
- char *strcpy(),*strncpy(),*strcat(),*sprintf(); /* for lint only */
-
- char *make_labl();
-
- extern BOOLEAN autoscale;
- extern FILE *outfile;
- extern BOOLEAN log_y;
- extern int term;
- extern BOOLEAN draw_border;
-
- extern BOOLEAN screen_ok;
- extern BOOLEAN term_init;
-
- extern double loff,roff,toff,boff;
- extern double zero;
-
- extern enum GRAV_DIR gravity, explode;
- extern int samples;
- extern double base;
- extern BOOLEAN p_clockwise, b_clockwise;
- extern double radexp, treshold;
- extern double b_wid, b_spc, b_int;
- extern char thrname[];
-
- extern float xsize, ysize;
-
- extern char tic_form[];
-
- extern enum FONT_STYLE vect_font;
-
- extern struct termentry term_tbl[];
- extern struct dfile data_head; /* static head of data list */
-
- extern struct label_def *first_label; /* defined in flblarr.c */
- extern struct linearrow_def *first_arrow; /* defined in flblarr.c */
-
- #ifndef toascii
- #define toascii(A) (((int)(A)) & 0x7F)
- #endif
-
- #define SIGN(A) (A>=0 ? 1 : -1)
-
- extern struct Char trt[]; /* font translation table */
-
- static struct termentry *t; /* faster */
- static int xbase, ybase, xmaxp, ymaxp; /* viewport */
- static struct xptr *across; /* used for xplot */
- static int first_element; /* first element for autolabeling */
- static BOOLEAN trotate; /* whether terminal can rotate text or not */
- static int tstate; /* state of terminal text rotation */
- static int howmuch; /* how much space takes as text the longest used value */
-
- do_plot(xplot,style,fel)
- BOOLEAN xplot;
- enum DRAW_STYLE style;
- int fel;
- {
- /**This bloody part of code initializes graphic *
- * environment, draws borders, outputs trailer, *
- * etc. Before calling drawing fuctions it cal- *
- * culates viewport (see toff,boff,roff,loff) *
- * and some other variables used in any style. *
- * Ough, how I long to Pascal's nested local *
- * procedures !!! */
-
- BOOLEAN dolabel = (data_head.fname != (char *)NULL);
- int effect, x, y, x0, dx, y0, dy;
- struct label_def *lb;
- struct linearrow_def *ar;
-
- t = &term_tbl[term];
- if (!(*t->scale)(xsize, ysize)) {
- x = t->xmax * xsize;
- y = t->ymax * ysize;
- }
- else {
- x = t->xmax;
- y = t->ymax;
- }
-
- y0 = ybase = (int) ((boff>1.0 ? boff/100.0 : boff)*y) + 1;
- dy = ymaxp = (int) ((1.0-(toff>1.0 ? toff/100.0 : toff))*(y-2)) - (dolabel ? 3*t->v_char : 0);
- if (ymaxp <= ybase)
- int_error("no space to put title, change offsets", NO_CARET);
- x0 = xbase = (int) ((loff>1.0 ? loff/100.0 : loff)*x) + 1;
- dx = xmaxp = (int) ((1.0-(roff>1.0 ? roff/100.0 : roff))*(x-2));
-
- across = (struct xptr *) data_head.data;
- first_element = fel;
-
- if (!term_init) {
- (*t->init)();
- term_init = TRUE;
- }
- screen_ok = FALSE;
- (*t->graphics)();
- trotate = (*t->text_angle)(0); /* mostly harmless */
- tstate = 0;
-
- switch (style) {
- case ABARS : effect = dr_abar(xplot);
- break;
- case SBAR : effect = dr_sbar(xplot);
- break;
- case LAYB : effect = dr_lbar(xplot);
- break;
- case PIECHART : effect = dr_pies(xplot);
- break;
- default :
- (*t->text)();
- (void) fflush(outfile);
- int_error("style not yet implemented",NO_CARET);
- }
-
- if (!effect) {
- (*t->text)();
- (void) fflush(outfile);
- int_error("too many data to make sensible picture", NO_CARET);
- }
-
- (*t->linetype)(-2); /* border linetype */
- if (draw_border) { /* draw plot border */
- (*t->move)(0,0);
- (*t->vector)(x-1,0);
- (*t->vector)(x-1,y-1);
- (*t->vector)(0,y-1);
- (*t->vector)(0,0);
- }
-
- (*t->linetype)(0); /* only one guaranted to be solid */
- if (dolabel) /* put title */
- put_txt((x0+dx)/2, (int)(dy+3*t->v_char/2), data_head.fname, CENTRE, 0);
-
- for (lb=first_label; lb; lb=lb->next) { /* process and put labels */
- double c_x = lb->x <= 1.0 ? lb->x : lb->x/RESOLUTION;
- double c_y = lb->y <= 1.0 ? lb->y : lb->y/RESOLUTION;
- double c_h = lb->h <= 1.0 ? lb->h : lb->h/RESOLUTION;
- double c_w = lb->w <= 1.0 ? lb->w : lb->w/RESOLUTION;
- int lx, ly, r_x, r_y, r0x, r0y;
- if (!*lb->text)
- continue;
-
- if (lb->paged) {
- r0x = r0y = 0;
- r_x = x; r_y = y;
- }
- else {
- r0x = x0; r0y = y0;
- r_x = dx-x0; r_y = dy-y0;
- }
- lx = r0x + c_x*r_x;
- ly = r0y + c_y*r_y;
-
- if ((lb->rot == L_NORMAL || lb->rot == L_BOTTOM) &&
- !lb->h && !lb->w) /* try to put it as a normal text */
- put_txt(lx, ly, lb->text, lb->pos, lb->rot==L_NORMAL ? 0 : 1);
- else {
- double an = (int)lb->rot * Pi/2;
- if (!lb->h && !lb->w) /* use standard size */
- (void) draw_text(lx, ly, lb->text, (int)t->v_char, 0, -1, lb->pos, lb->rot==L_RANDOM ? lb->a : an);
- else /* draw_text will worry */
- (void) draw_text(lx, ly, lb->text, (int)(c_h*r_y), (int)(c_w*r_x),
- -1, lb->pos, lb->rot==L_RANDOM ? lb->a : an);
- }
- }
-
- for (ar=first_arrow; ar; ar=ar->next) { /* process and put arrows/lines */
- double c_sx = ar->sx <= 1.0 ? ar->sx : ar->sx/RESOLUTION;
- double c_sy = ar->sy <= 1.0 ? ar->sy : ar->sy/RESOLUTION;
- double c_ex = ar->ex <= 1.0 ? ar->ex : ar->ex/RESOLUTION;
- double c_ey = ar->ey <= 1.0 ? ar->ey : ar->ey/RESOLUTION;
- int sx,sy,ex,ey;
- if (ar->startp) {
- sx = x*c_sx;
- sy = y*c_sy;
- }
- else {
- sx = x0 + (dx-x0)*c_sx;
- sy = y0 + (dy-y0)*c_sy;
- }
- if (ar->endp) {
- ex = x*c_ex;
- ey = y*c_ey;
- }
- else {
- ex = x0 + (dx-x0)*c_ex;
- ey = y0 + (dy-y0)*c_ey;
- }
-
- if (ar->arrow)
- (*t->arrow)(sx, sy, ex, ey);
- else {
- (*t->move)(sx, sy);
- (*t->vector)(ex, ey);
- }
- }
-
- (*t->text)();
- (void) fflush(outfile);
- }
-
- #define MCx(PT,R,AN) nint((PT)+(R)*cos(AN))
- #define MCy(PT,R,AN) nint((PT)+(R)*sin(AN))
-
- put_arc(x,y,r,a0,da)
- int x,y,r;
- double a0,da;
- /* draw arc from a0, da long */
- {
- double step, drto;
- int iter;
-
- (*t->move)(MCx(x,r,a0),MCy(y,r,a0));
- step = 2*Pi/samples * (da>0.0 ? 1 : -1); /* angle step */
- iter = nint(floor(da/step)); /* number of iterations - makes loop faster */
- drto = a0 + step; /* next place to draw */
- while (iter--) {
- (*t->vector)(MCx(x,r,drto),MCy(y,r,drto));
- drto += step;
- }
- (*t->vector)(MCx(x,r,a0+da),MCy(y,r,a0+da)); /* last part - prob. shorter */
- }
-
- put_bar(x0,y0,dx,dy,turn)
- int x0,y0,dx,dy,turn;
- /* put single bar (opened rectangle) */
- {
- if (turn) (*t->move)(x0,y0+dy);
- else {
- (*t->move)(x0,y0);
- (*t->vector)(x0,y0+dy);
- }
- (*t->vector)(x0+dx,y0+dy);
- (*t->vector)(x0+dx,y0);
- if (turn)
- (*t->vector)(x0,y0);
- }
-
- BOOLEAN find_ran(min, max, sum, lab)
- double *min, *max, *sum;
- char **lab; /* NULL if all labels undefined; "" if labels different; else pointer to the good label */
- /**find function used for stacked bars: find min, max and total sum across all data. *
- * Check also possibility of labelling across etc. */
- {
- int i;
- vreal w;
- static char nothing[] = "";
- int labfound = 1;
- char *good = NULL, *aux;
-
- *min = VERYLARGE;
- *max = -VERYLARGE;
- *sum = 0.0;
- for (i=0; i<data_head.chunks; i++) {
- if (!across[i].chnp || (w=across[i].chnp->dval[across[i].vindex]) == VERYLARGE) continue;
- if (*min > w) *min = w;
- if (*max < w) *max = w;
- *sum += w;
- if (labfound && across[i].chnp->vlbl && (aux = across[i].chnp->vlbl[across[i].vindex]))
- if (!good) /* first found */
- good = aux;
- else
- labfound = !strcmp(good,aux);
- }
-
- if (!good) /* no label found, all undefined */
- *lab = NULL;
- else if (labfound) /* all labels are the same -- return any */
- *lab = good;
- else /* different -- return fake label (will be processed in function, but rejected later) */
- *lab = nothing;
-
- if (*min == VERYLARGE || *max == -VERYLARGE) /* all points undefined */
- return(FALSE);
- else
- return(TRUE);
- }
-
- char *comm_lget()
- /* check labels (like find_ran above), but also advance pointers */
- {
- int i, j;
- static char nothing[] = "";
- int labfound = 1;
- char *good = NULL, *aux;
-
- for (i=0; i<data_head.chunks; i++) {
- if (!across[i].chnp) continue;
- j = across[i].vindex;
- if (across[i].chnp->dval[j] != VERYLARGE && across[i].chnp->vlbl && (aux = across[i].chnp->vlbl[j]))
- if (!good) /* first found */
- good = aux;
- else
- labfound = !strcmp(good,aux);
- if (++across[i].vindex == across[i].chnp->used) {
- across[i].chnp = across[i].chnp->next;
- across[i].vindex = 0;
- }
- }
-
- if (!good) /* no label found, all undefined */
- return (NULL);
- else if (labfound) /* all labels are the same -- return any */
- return (good);
- else
- return (nothing);
- }
-
- do_axis(a1,a2,xb,xm,yb,ym,reserved)
- double *a1, *a2;
- int xb, xm, yb, ym;
- BOOLEAN reserved; /* should we shrink drawing area, or there's enough space ? */
- /* draws axis for bars, reserve space for values, put tickmarks with labels */
- {
- double minv = *a1, maxv = *a2, tick, minpl, maxpl, unit;
- int dirNS = !((int)gravity&1);
- int i, j, space;
-
- space = dirNS ? (ym-yb)/t->v_char : (xm-xb)/t->h_char;
- if (minv == maxv)
- tick=0;
- else if (log_y) {
- minpl = minv = floor(minv)+log10(2.0)<minv ? floor(minv)+log10(2.0) : floor(minv);
- maxpl = maxv = ceil(maxv)-log10(2.0)>maxv ? ceil(maxv)-log10(2.0) : ceil(maxv);
- tick = floor(log10(maxv-minv))+1;
- }
- else {
- double aux = fabs(minv)>fabs(maxv) ? fabs(minv) : fabs(maxv);
- tick = exp10(floor(log10(aux)));
- aux = exp10(floor(log10(aux)-1));
- minpl = tick * ceil(minv/tick);
- maxpl = tick * floor(maxv/tick);
- minv = aux * floor(minv/aux);
- maxv = aux * ceil(maxv/aux);
- if ((maxv-minv)/tick <= 3.0) {
- int flip = 1;
- do {
- tick /= flip ? 2.0 : 5.0;
- flip = 1-flip;
- minpl = tick * ceil(minv/tick);
- maxpl = tick * floor(maxv/tick);
- } while ((maxv-minv)/tick <= 3.0);
- }
- if ((maxpl-minpl)/tick >= (double)space) {
- int flip = 1;
- do {
- tick *= flip ? 5.0 : 2.0;
- flip = 1-flip;
- minpl = tick * ceil(minv/tick);
- maxpl = tick * floor(maxv/tick);
- } while ((maxpl-minpl)/tick >= (double)space);
- }
- }
-
- if (!tick) return(0);
-
- unit = (dirNS ? ym-yb : xm-xb)/(maxv-minv);
- (*t->linetype)(0); /* solid linetype */
- switch (gravity) {
- case SOUTH:
- if (!reserved)
- xb += t->h_char*howmuch + 2*t->h_tic;
- j = xb - 2*t->h_tic;
- (*t->move)(xb,yb);
- (*t->vector)(xb,ym);
- (*t->linetype)(0); /* the only type solid for sure */
- while (minpl<=maxpl) {
- (*t->move)(xb,i=yb+nint((minpl-minv)*unit));
- (*t->vector)(xb-t->h_tic,i);
- put_txt(j, i, make_labl((double) (log_y ? exp10(minpl) : minpl)), RIGHT, 0);
- minpl += tick;
- }
- break;
- case NORTH:
- if (!reserved)
- xm -= t->h_char*howmuch + 2*t->h_tic;
- j = xm + 2*t->h_tic;
- (*t->move)(xm,yb);
- (*t->vector)(xm,ym);
- (*t->linetype)(0); /* the only type solid for sure */
- while (minpl<=maxpl) {
- (*t->move)(xm,i=ym-nint((minpl-minv)*unit));
- (*t->vector)(xm+t->h_tic,i);
- put_txt(j, i, make_labl((double) (log_y ? exp10(minpl) : minpl)), LEFT, 0);
- minpl += tick;
- }
- break;
- case WEST:
- if (!reserved)
- ym -= t->v_char*howmuch + 2*t->v_tic;
- j = ym + 2*t->v_tic;
- (*t->move)(xb,ym);
- (*t->vector)(xm,ym);
- (*t->linetype)(0); /* the only type solid for sure */
- while (minpl<=maxpl) {
- (*t->move)(i=xb+nint((minpl-minv)*unit),ym);
- (*t->vector)(i,ym+t->v_tic);
- put_txt(i, j, make_labl((double) (log_y ? exp10(minpl) : minpl)), LEFT, 1);
- minpl += tick;
- }
- break;
- case EAST:
- if (!reserved)
- yb += t->v_char*howmuch + 2*t->v_tic;
- j = yb - 2*t->v_tic;
- (*t->move)(xm,yb);
- (*t->vector)(xb,yb);
- (*t->linetype)(0); /* the only type solid for sure */
- while (minpl<=maxpl) {
- (*t->move)(i=xm-nint((minpl-minv)*unit),yb);
- (*t->vector)(i,yb-t->v_tic);
- put_txt(i, j, make_labl((double) (log_y ? exp10(minpl) : minpl)), RIGHT, 1);
- minpl += tick;
- }
- break;
- }
-
- *a1 = minv; *a2 = maxv;
- return ( (int) (2*(dirNS ? t->h_tic : t->v_tic) + howmuch*(dirNS ? t->h_char : t->v_char)) );
- /* if (reserved), return value is rejected, so it doesn't matter */
- }
-
- /* from hereon go different labeling functions. The basic one is the first */
-
- int draw_text(x, y, s, h, w, tc, just, an)
- int x, y, h, w, tc;
- char *s;
- enum JUSTIFY just;
- double an;
- /* draw text in vector font and return useful info - complementary of h parameter */
- {
- int wid, k, retv, rwid;
- char *p;
- double sc;
- int *d;
- MATRIX R, S, A;
-
- if (!s || !*s || !tc || !h && !w)
- return(0); /* nothing useful can be done */
- if (tc>0 && tc < strlen(s))
- s[tc] = '\0'; /* truncate */
-
- for (p=s, wid=0; *p; p++)
- if (!trt[*p=toascii(*p)].wid)
- wid += trt[0].wid + CHAR_OFF;
- else
- wid += trt[*p].wid + CHAR_OFF;
- rwid = wid;
-
- rotat(-an, R); /* rotate object system (!) */
-
- if (h) {
- sc = (double)(h) / (double)CHAR_GRD;
- wid *= sc;
- retv = wid;
- }
- else
- wid = 0;
- if (!wid || w && wid > w) { /* can't with with desired height -- try to schrink */
- sc = (double)(w)/(double)(rwid);
- wid = w;
- retv = CHAR_GRD*sc; /* return text height */
- }
- scale(sc, sc, S);
- multi(S, R, A);
-
- switch (just) {
- case LEFT: break;
- case CENTRE: {
- wid /= 2; /* and no break */
- }
- case RIGHT: {
- x -= (double)wid*cos(an); /* rotate within coordinate system */
- y -= (double)wid*sin(an);
- }
- }
- if (x<0 || y<0)
- return(0); /* nothing useful - failed */
-
- #ifdef NO_ROMAN_FONT
-
- x += (CHAR_OFF/2)*A[0][0]+A[0][2];
- y += (CHAR_OFF/2)*A[1][0]+A[1][2];
-
- #define MX(v) nint( (*(v))*A[0][0] + (*(v+1))*A[0][1] + A[0][2] )
- #define MY(v) nint( (*(v))*A[1][0] + (*(v+1))*A[1][1] + A[1][2] )
-
- {
- unsigned char *u;
- int i,j;
- for ( ; *s; wid=trt[*s].wid, x+=(wid+CHAR_OFF)*A[0][0]+A[0][2], y+=(wid+CHAR_OFF)*A[1][0]+A[1][2], s++) {
- if (!trt[c=*s].wid) c='\0';
- for (i=0; i<3 && (u=trt[c].def[i]); i++) {
- (*t->move) (x+MX(u), y+MY(u));
- while (*(u+=2))
- (*t->vector) (x+MX(u), y+MY(u));
- }
- }
- }
-
- #undef MX
- #undef MY
-
- #else /* another algorithm: for roman font */
-
- x -= (CHAR_OFF/2)*A[0][0]+A[0][2];
- y -= (CHAR_OFF/2)*A[1][0]+A[1][2];
-
- #define MX(v) nint( ((v)/100)*A[0][0] + ((v)%100)*A[0][1] + A[0][2] )
- #define MY(v) nint( ((v)/100)*A[1][0] + ((v)%100)*A[1][1] + A[1][2] )
-
- for ( ; *s; wid=trt[*s].wid, x+=(wid+CHAR_OFF)*A[0][0]+A[0][2], y+=(wid+CHAR_OFF)*A[1][0]+A[1][2], s++)
- for (d=trt[*s].def; *d; d++)
- if ((k=*d)<0) {
- k = abs(k);
- (*t->move)(x+MX(k), y+MY(k));
- }
- else
- (*t->vector)(x+MX(k), y+MY(k));
-
- #undef MX
- #undef MY
-
- #endif
-
- return(retv);
- }
-
- make_just(x, y, j, l, d)
- int *x, *y;
- int l, d; /* l != 0 */
- enum JUSTIFY j;
- /* set terminal justification */
- {
- if (!d) {
- if (j == LEFT)
- (void) (*t->justify_text)(LEFT);
- else if ((*t->justify_text)(j)) ;
- else if (j == CENTRE)
- *x -= t->h_char * l/2;
- else if (j == RIGHT)
- *x -= t->h_char * l;
- else /* impossible */ return;
- }
- else {
- if (j == LEFT)
- (void) (*t->justify_text)(LEFT);
- else if ((*t->justify_text)(j)) ;
- else if (j == CENTRE)
- *y -= t->h_char * l/2;
- else if (j == RIGHT)
- *y -= t->h_char * l;
- else /* impossible */ return;
- }
- }
-
- put_txt(x,y,s,j,d)
- int x, y, d;
- char *s;
- enum JUSTIFY j;
- /* put any text on given position, with standard size, sideways or rotated +Pi/2 */
- {
- if (!s || !*s) return;
- if ((trotate || !d) && vect_font == F_WHENN || /* terminal can or need not rotate */
- vect_font == F_NEVER) { /* never use vector font, regardles of anything */
- if (tstate != d)
- (*t->text_angle)(tstate = d);
- make_just(&x, &y, j, strlen(s), d);
- (*t->put_text)(x, y, s);
- }
- else { /* use vector font */
- int i = t->v_char;
- if (d)
- x += t->h_char/2; /* draw_text takes lower-left corner */
- else
- y -= t->h_char/2;
- (void) draw_text(x, y, s, i, 0, -1, j, d*Pi/2);
- }
- }
-
- put_lab(x,y,s,d,size)
- int x, y, d, size;
- char *s;
- /* put label centered around (x,y), fitting it within given size, use vector font if only allowed */
- {
- int i, j, l;
-
- if (!s || !*s || size<=0)
- return; /* nothing useful */
-
- j = size / t->h_char; /* number of standard chars that can fit */
- i = (l=strlen(s)) < howmuch ? howmuch : l; /* how many chars should we fit ? */
-
- if (vect_font == F_NEVER || /* never use vector font */
- !d && i <= j && vect_font != F_ALWYS) { /* horizontal, fits within req. size, no need for font */
- if (tstate != d)
- (*t->text_angle)(tstate = d);
- make_just(&x, &y, CENTRE, strlen(s), d);
- (*t->put_text)(x, y, s);
- }
- else { /* pain in the ass */
- if (d)
- x += t->h_char/2; /* draw_text takes lower-left corner */
- else
- y -= t->v_char/2;
- i = t->v_char;
- (void) draw_text(x, y, s, i, size, -1, CENTRE, d*Pi/2);
- }
- }
-
- char *make_labl(d)
- double d;
- {
- static char buf[200];
- if (d == VERYLARGE || d== -VERYLARGE)
- return(NULL); /* will be rejected later */
- sprintf(buf, tic_form, (float) d); /* it's float from user point of view, and compatibility with Gnuplot */
- return(buf);
- }
-
- set_hm(min, max)
- double min, max;
- /* find space needed for ticks */
- {
- char buf[200];
- int i;
- sprintf(buf, tic_form, (float) min);
- howmuch = strlen(buf);
- sprintf(buf, tic_form, (float) max);
- if (howmuch < (i=strlen(buf)))
- howmuch = i;
- }
-
- init_acrs()
- /* init across pointer structure */
- {
- struct dfile *f = &data_head;
- int i = 0;
-
- while (f = f->dnxt) {
- across[i].chnp = f->data;
- across[i++].vindex = 0;
- }
- }
-
- /* test terminal by drawing border and text */
- /* called from command test */
- term_test()
- /* don't use original test_term() from term.c */
- {
- char *str;
- int x,y, xl,yl, i;
- char label[MAX_LINE_LEN];
-
- t = &term_tbl[term];
- if (!term_init) {
- (*t->init)();
- term_init = TRUE;
- }
- screen_ok = FALSE;
- (*t->graphics)();
- /* border linetype */
- (*t->linetype)(-2);
- (*t->move)(0,0);
- (*t->vector)(t->xmax-1,0);
- (*t->vector)(t->xmax-1,t->ymax-1);
- (*t->vector)(0,t->ymax-1);
- (*t->vector)(0,0);
- (void) (*t->justify_text)(LEFT);
- (*t->put_text)(t->h_char*5,t->ymax-t->v_char*3,"Terminal Test");
- (*t->linetype)(0);
- (*t->arrow)(t->h_char*5, t->ymax-t->v_char*5, t->h_char*5, t->ymax/2+t->v_char);
- /* axis linetype */
- (*t->linetype)(-1);
- (*t->move)(t->xmax/2,0);
- (*t->vector)(t->xmax/2,t->ymax-1);
- (*t->move)(0,t->ymax/2);
- (*t->vector)(t->xmax-1,t->ymax/2);
- /* test width and height of characters */
- (*t->linetype)(-2);
- (*t->move)( t->xmax/2-t->h_char*10,t->ymax/2+t->v_char/2);
- (*t->vector)(t->xmax/2+t->h_char*10,t->ymax/2+t->v_char/2);
- (*t->vector)(t->xmax/2+t->h_char*10,t->ymax/2-t->v_char/2);
- (*t->vector)(t->xmax/2-t->h_char*10,t->ymax/2-t->v_char/2);
- (*t->vector)(t->xmax/2-t->h_char*10,t->ymax/2+t->v_char/2);
- (*t->put_text)(t->xmax/2-t->h_char*10,t->ymax/2,
- "12345678901234567890");
- /* test justification */
- (void) (*t->justify_text)(LEFT);
- (*t->put_text)(t->xmax/2,t->ymax/2+t->v_char*5,"left justified");
- str = "centre+d text";
- if ((*t->justify_text)(CENTRE))
- (*t->put_text)(t->xmax/2,
- t->ymax/2+t->v_char*4,str);
- else
- (*t->put_text)(t->xmax/2-strlen(str)*t->h_char/2,
- t->ymax/2+t->v_char*4,str);
- str = "right justified";
- if ((*t->justify_text)(RIGHT))
- (*t->put_text)(t->xmax/2,
- t->ymax/2+t->v_char*3,str);
- else
- (*t->put_text)(t->xmax/2-strlen(str)*t->h_char,
- t->ymax/2+t->v_char*3,str);
- /* test text angle */
- str = "rotated ce+ntred text";
- if ((*t->text_angle)(1)) {
- if ((*t->justify_text)(CENTRE))
- (*t->put_text)(t->v_char,
- t->ymax/2,str);
- else
- (*t->put_text)(t->v_char,
- t->ymax/2-strlen(str)*t->h_char/2,str);
- }
- else {
- (void) (*t->justify_text)(LEFT);
- (*t->put_text)(t->h_char*2,t->ymax/2-t->v_char*2,"Can't rotate text");
- }
- (void) (*t->justify_text)(LEFT);
- (void) (*t->text_angle)(0);
- /* test tic size */
- (*t->move)(t->xmax/2+t->h_tic*2,0);
- (*t->vector)(t->xmax/2+t->h_tic*2,t->v_tic);
- (*t->move)(t->xmax/2,t->v_tic*2);
- (*t->vector)(t->xmax/2+t->h_tic,t->v_tic*2);
- (*t->put_text)(t->xmax/2+t->h_tic*2,t->v_tic*2+t->v_char/2,"test tics");
- /* test line and point types */
- x = t->xmax - t->h_char*4 - t->h_tic*4;
- y = t->ymax - t->v_char;
- for ( i = -2; y > t->v_char; i++ ) {
- (*t->linetype)(i);
- (void) sprintf(label,"%d",i);
- if ((*t->justify_text)(RIGHT))
- (*t->put_text)(x,y,label);
- else
- (*t->put_text)(x-strlen(label)*t->h_char,y,label);
- (*t->move)(x+t->h_char,y);
- (*t->vector)(x+t->h_char*4,y);
- y -= t->v_char;
- }
- /* test bars */
- (*t->linetype)(-1);
- x = t->xmax/2 + t->xmax/12;
- y = t->ymax/6;
- xl = t->xmax/32;
- yl = t->ymax/32;
- (*t->move)(x,y);
- (*t->vector)(x+xl*6,y);
- x += xl/4;
- for (i=1; i<=4; i++, x+=xl*3/2) {
- (*t->linetype)(i-1);
- put_bar(x,y,xl,i*yl,FALSE);
- }
- /* test pies */
- (*t->linetype)(0);
- x = t->xmax/4;
- y = t->ymax/4;
- i = 3*(t->xmax < t->ymax ? t->xmax : t->ymax)/32;
- xl = MCx(0,i,Pi/4);
- yl = MCy(0,i,Pi/4);
- (*t->move)(x+xl,y+yl);
- (*t->vector)(x-xl,y-yl);
- (*t->move)(x-xl,y+yl);
- (*t->vector)(x+xl,y-yl);
- put_arc(x,y,i,Pi/4,3*Pi/2);
- sprintf(label,"(pie sampling is %d)",samples);
- put_txt(x,y-yl-2*(int)(t->v_char),label,CENTRE,0);
- x += t->xmax/32;
- (*t->move)(x+xl,y-yl);
- (*t->vector)(x,y);
- (*t->vector)(x+xl,y+yl);
- put_arc(x,y,i,Pi/4,-Pi/2);
-
- /* experimental code */
- (*t->linetype)(0);
- x = t->xmax/2 + t->xmax/32;
- y = t->ymax*9/10;
- i = t->v_char;
- x += draw_text(x, y, "experimental", i, 0, -1, LEFT, 0.0);
- i = draw_text(x, y, "scalable", i*2, 0, -1, LEFT, -Pi/4);
- x += i*cos(-Pi/4); y += i*sin(-Pi/4);
- (void) draw_text(x, y, "vector font", 0, (int)(t->xmax/16), -1, LEFT, -Pi/2);
- y -= (int)(t->xmax/16);
- (void) draw_text(x, y, "0123456789", 0, (int)(t->xmax/8), -1, LEFT, -Pi);
-
- /* and back into text mode */
- (*t->text)();
- (void) fflush(outfile);
- }
-
-
-
-
-
-
-
-
-
-
- /* included file contains an old version of graphics routines */
-
- #include "fstyles.i"
-
-
-
-
-
-